﻿using System.Collections.Generic;
using KnightWeapons;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UI;

public class PropManager : NetworkBehaviour
{
    public static PropManager Instance;
    [SerializeField] GameObject propPanel;
    [SerializeField] GameObject playerStatePanel;
    [SerializeField] GameObject playerStatePrefab;
    [SerializeField] Button refreshBT;
    [SerializeField] Button nextLevelBT;
    [SerializeField] TextMeshProUGUI moneyText;
    [SerializeField] List<PropData> propData;
    [SerializeField] List<PropUI> holdPropUIs;
    Dictionary<ulong, PlayerStateUI> playerStates=new();
    
    private void Awake()
    {
        if (Instance == null)
            Instance = this;
        else if (Instance != this)
            Destroy(gameObject);        
    }

    private void Start()
    {
        refreshBT.onClick.AddListener(ReSetProp);
        propPanel.SetActive(false);
    }

    public override void OnNetworkSpawn()
    {
        MyEvenSystem.OnPlayerMoneyChanged += UpdateMoney;

        if (IsHost)
        {
            nextLevelBT.onClick.AddListener(OnNextLevelBTClick);
        }
        else
        {
            nextLevelBT.GetComponentInChildren<TextMeshProUGUI>().text = "准备";
            nextLevelBT.onClick.AddListener(() =>
            {
                NotifyReadyStateRpc(NetworkManager.LocalClientId);
            });            
        }        

        MultiPlayManager.Instance.Players.OnListChanged += Players_OnListChanged;        
        foreach (var player in MultiPlayManager.Instance.Players)
        {
            if(playerStates.ContainsKey(player.id))
            {                
                continue;
            }
            var obj = Instantiate(playerStatePrefab, playerStatePanel.transform);
            var ui = obj.GetComponent<PlayerStateUI>();
            playerStates[player.id] = ui;
        }
    }

    public override void OnNetworkDespawn()
    {
        MyEvenSystem.OnPlayerMoneyChanged -= UpdateMoney;

        MultiPlayManager.Instance.Players.OnListChanged -= Players_OnListChanged;
    }

    // 监听玩家列表变化，移除对应UI
    private void Players_OnListChanged(NetworkListEvent<PlayerData> changeEvent)
    {
        switch (changeEvent.Type)
        {
            case NetworkListEvent<PlayerData>.EventType.Remove:                
            case NetworkListEvent<PlayerData>.EventType.RemoveAt:
                {
                    RemovePlayerStateUI(changeEvent.Value.id);
                    break;
                }
        }
    }

    void RemovePlayerStateUI(ulong clientID)
    {
        if(playerStates.TryGetValue(clientID, out var ui))
        {
            if (ui != null)
            {
                Destroy(ui.gameObject);
                playerStates.Remove(clientID);
            }
            else
                Debug.LogWarning("UI of " + clientID+" is null");
        }
        else
        {
            Debug.Log("don't find UI of " + clientID);
        }
    }

    [Rpc(SendTo.ClientsAndHost)]
    void NotifyReadyStateRpc(ulong clientID)
    {
        playerStates[clientID].SetReadyState();
    }
     
    public PropData GetRandomPropData(PropData data)
    {                
        int randNum = Random.Range(0, propData.Count);
        if (propData[randNum] == data)
        {
            if (randNum < propData.Count - 1)
                randNum++;
            else if(randNum>0)
                randNum--;
        }
        return propData[randNum];
    }

    void OnNextLevelBTClick()
    {
        foreach(var ui in playerStates)
        {
            if (!ui.Value.IsReady && ui.Key != 0)
            {
                Debug.Log("玩家 " + ui.Key + " 未准备");
                return;
            }
        }
        LevelManager.Instance.StartLevel();
    }

    public void ReSetProp()
    {
        foreach(var ui in holdPropUIs)
        {
            ui.Init(GetRandomPropData(ui.Data));
        }
    }

    public bool TryBuyProp(PropUI propUI)
    {
        var knight = Knight.Instance;
        if (knight.Money >= propUI.Data.Cost)
        {
            knight.Money-= propUI.Data.Cost;
            propUI.Data.Effect.OnUse(knight);
            propUI.Init(GetRandomPropData(propUI.Data));
            return true;
        }
        else
            return false;
    }

    void UpdateMoney(int money)
    {
        if(propPanel.activeInHierarchy)
            moneyText.text = money.ToString();
    }

    public void EnableChoose()
    {
        propPanel.SetActive(true);
        
        UpdateMoney(Knight.Instance.Money);
        foreach (var ui in playerStates)
        {
            if (ui.Value.IsReady && ui.Key != 0)
                ui.Value.ReSetState();
        }
        ReSetProp();
    }

    public void DisableChoose()
    {
        propPanel.SetActive(false);
    }
}
